import json,os,random,string,copy
import modclass as md
class modData():


    def generate_random_number(self):
        while True:
            random_number = random.randrange(-2100000000, 2100000000)
            if -1000000 <= random_number <= 100000000:
                continue
            else:
                return random_number
            
    def getUuid(self,ids=[],key=False):
        if key:
            letters = string.ascii_letters
            random_string = ''.join(random.choice(letters) for _ in range(8))
            while random_string in ids:                
                random_string = ''.join(random.choice(letters) for _ in range(8))
            ids.append(random_string)
            return random_string
        
        else:
            res = self.generate_random_number()
            while res in ids:
                res= self.generate_random_number()
            ids.append(res)
            return res

    def obj_copy(self,obj,key):
        res=copy.deepcopy(obj)

        if key=="localText":
            res['key']['value']=self.getUuid(self.LocalText_Key,True)
            res['id']['value']=self.getUuid(self.LocalText_ids)
            return res
        
        if key =="condition":
            res['id']['value']=self.getUuid(self.condition_ids)
            return res
        
        if key=="dramaOptions":
            res['id']['value']=self.getUuid(self.dramaDialogue_ids)            
            res['text']=self.obj_copy(res['text'],'localText')
            res['costItem']=self.obj_copy(res['costItem'],'costItem')
            return res

        if key=="rewardCount":
            res['rewardID']['value']=self.getUuid(self.GameItemReward_rewardids)
            for r in res['items']:
                r['id']['value']=self.getUuid(self.GameItemReward_ids)
                conditions=[]
                for c in r['condition']['items']:
                    c=self.obj_copy(c,"condition")
                    conditions.append(c)
                r['condition']['items']=conditions
            return res
        
        if key =="function":
            key_function=res['key']['value']
            res['id']['value']=self.getUuid(self.function_ids)
            if key_function=='rewardCount':
                obj_json=json.loads(res['values'][0]['value'])
                obj_json=self.obj_copy(obj_json,key_function)
                res['values'][0]['value']=json.dumps(obj_json,ensure_ascii=False)

            return res

        if key=="dramaDialogue":            
            res['id']['value']=self.getUuid(self.dramaDialogue_ids)
            res['dialogue']=self.obj_copy(res['dialogue'],'localText')
            res['title']=self.obj_copy(res['title'],'localText')
            dramaOptions=[]
            for o in res['dramaOptions']['items']:
                o=self.obj_copy(o,"dramaOptions")
                functions=[]
                for f in o['function']['items']:
                    f=self.obj_copy(f,"function")                
                    functions.append(f)
                o['function']['items']=functions
                dramaOptions.append(o)        
            res['dramaOptions']['items']=dramaOptions
                
            conditions=[]
            for c in  res['condition']['items']:
                c=self.obj_copy(c,"condition")    
                conditions.append(c)
            res['condition']['items']=conditions

            functions=[]
            for c in  res['function']['items']:
                c=self.obj_copy(c,"function")       
                functions.append(c)
            res['function']['items']=functions

            functions=[]
            for c in  res['openFunction']['items']:
                c=self.obj_copy(c,"function")     
                functions.append(c)  
            res['openFunction']['items']=functions
            return res

        if key=='roleCreateFeature':
            res['id']['value']=self.getUuid(self.roleCreateFeature_ids)
            res['name']=self.obj_copy(res['name'],'localText')
            res['tips']=self.obj_copy(res['tips'],'localText')
            res['type1Data']['introduceText']=self.obj_copy(res['type1Data']['introduceText'],'localText')
            res['type3Data']['desc']=self.obj_copy(res['type3Data']['desc'],'localText')
            effects=[]
            for e in res['effect']['items']:
                e=self.obj_copy(e,"effect")
                effects.append(e)
            res['effect']['items']=effects 
            return res

        if key=='effect':
            res['id']['value']=self.getUuid(self.effect_ids)
            res['roleEffect']['id']['value']=self.getUuid(self.roleEffect_ids)
            if res['roleEffect']['values'][0]['value']=="createNpc":
                obj_json=json.loads(res['roleEffect']['values'][1]['value'])
                res['roleEffect']['values'][1]=json.dumps(self.obj_copy(obj_json,"createNpc"),ensure_ascii=False)
            return res
        
        if key=='createNpc':
            res['id']['value']=self.getUuid(self.NpcSpecial_ids)
            res['dressMan']['id']['value']=self.getUuid(self.dress_ids)
            res['dressWoman']['id']['value']=self.getUuid(self.dress_ids)
            return res

        if key=='fortuitousEvent':
            res['id']['value']=self.getUuid(self.fortuitousEvent_ids)
            conditions=[]
            functions=[]
            for c in res['condition']['items']:
                c=self.obj_copy(c,"condition")      
                conditions.append(c)
            for c in res['function']['items']:
                c=self.obj_copy(c,"function") 
                functions.append(c)
            res['condition']['items']=conditions 
            res['function']['items']=functions 
            return res
        

        if key=='npcCondition':
            res['id']['value']=self.getUuid(self.npcCondition_ids)
            conditions=[]

            for c in res['condition']['items']:
                c=self.obj_copy(c,"condition")   
                conditions.append(c)
            res['condition']['items']=conditions
            return res 


        if key=='mapPosition':
            res['id']['value']=self.getUuid(self.mapPosition_ids)
            return res 

        if key=='worldFortuitousEventBase':
            res['id']['value']=self.getUuid(self.worldFortuitousEventBase_ids)
            res['name']=self.obj_copy(res['name'],'localText')   
            functions=[]
            for c in res['moveOnFunction']['items']:
                c=self.obj_copy(c,"function") 
                functions.append(c)
            res['moveOnFunction']['items']=functions
            functions=[]
            for c in res['createFunction']['items']:
                c=self.obj_copy(c,"function") 
                functions.append(c)
            res['createFunction']['items']=functions
            return res 

        if key=='itemProps':
            res['id']['value']=self.getUuid(self.itemProps_ids)
            res['name']=self.obj_copy(res['name'],'localText')   
            res['desc']=self.obj_copy(res['desc'],'localText')   

            res['itemPill']['roleEffect']['id']['value']=self.getUuid(self.roleEffect_ids)
            #马的属性
            res['itemHorse']=self.obj_copy(res['itemHorse'],'itemHorse')
            #藏宝图消耗物品
            res['itemTreasureMap']['costItem']=self.obj_copy(res['itemTreasureMap']['costItem'],"costItem")
            #戒指属性
            #层级过深的数据在修改的时候不会同时修改他的原对象，不能理解为什么！
            eff_ring=[]
            for eff in res['itemRing']['effectValue']['items']:
                eff=self.obj_copy(eff,"effect")
                eff_ring.append(eff)
            res['itemRing']['effectValue']['items']=eff_ring

            return res 
        

        if key =="itemHorse":
            res['desc']=self.obj_copy(res['desc'],'localText')   
            eff_new=[]
            for eff in res['effectValue']['items']:
                eff=self.obj_copy(eff,"effect")
                #层级过深的数据在修改的时候不会同时修改他的原对象，不能理解为什么！
                eff_new.append(eff)
            res['effectValue']['items']=eff_new
            return res
        
        if key =="costItem":
            res['id']['value']=self.getUuid(self.GameItemCost_ids)
            return res    
            
        if key =="taskBase":
            res['id']['value']=self.getUuid(self.taskBase_ids)
            res['name']=self.obj_copy(res['name'],'localText')   
            res['desc']=self.obj_copy(res['desc'],'localText')             
            functions=[]
            for c in res['completeTaskFunction']['items']:
                c=self.obj_copy(c,"function") 
                functions.append(c) 
            res['completeTaskFunction']['items']=functions
            return res

        
        if key =='dramaNpc':
            res['id']['value']=self.getUuid(self.dramaNpc_ids)
            res['name']=self.obj_copy(res['name'],'localText') 
            return res    
            
        
        if key =="npcAddWorld":
            res['id']['value']=self.getUuid(self.npcAddWorld_ids)
            res['name1']=self.obj_copy(res['name1'],'localText')   
            res['name2']=self.obj_copy(res['name2'],'localText')               
            res['dressMan']['id']['value']=self.getUuid(self.dress_ids)
            res['dressWoman']['id']['value']=self.getUuid(self.dress_ids)
            return res    
            
           
        
        if key =='schoolInitScale':
            res['id']['value']=self.getUuid(self.schoolInitScale_ids)
            res['lastName']=self.obj_copy(res['lastName'],'localText')   
            return res    
            
        
        if key =='schoolSmall':
            res['id']['value']=self.getUuid(self.schoolSmall_ids)
            res['lastName']=self.obj_copy(res['lastName'],'localText')   
            return res    
        
        if key =='horseModel':
            res['id']['value']=self.getUuid(self.horseModel_ids) 
            return res    
            
        if key=='dungeonBase':
            res['id']['value']=self.getUuid(self.dungeonBase_ids)
            #精英怪
            elite=[]
            for e in res['unitEliteUnitAttr']['items']:
                e= self.obj_copy(e,"unitEliteUnitAttr")
                elite.append(e)
            res['unitEliteUnitAttr']['items']=elite  
            #boss
            elite=[]
            for e in res['unitBossUnitAttr']['items']:
                e= self.obj_copy(e,"unitBossUnitAttr")
                elite.append(e)
            res['unitBossUnitAttr']['items']=elite  
            #普通怪 
            elite=[]
            for e in res['unitCommonUnitAttr']['items']:
                e= self.obj_copy(e,"unitCommonUnitAttr")
                elite.append(e)
            res['unitCommonUnitAttr']['items']=elite  
            
            return res


        if key in ['unitEliteUnitAttr','unitBossUnitAttr','unitCommonUnitAttr']:
            res['id']['value']=self.getUuid(self.BattleUnitAttr_ids)
            res['name']=self.obj_copy(res['name'],'localText') 
            res['dropID']=self.obj_copy(res['dropID'],"rewardCount")
            res['firstReward']=self.obj_copy(res['dropID'],"rewardCount")
            for scale in res['attrScale']['items']:
                scale['id']['value']=self.getUuid(self.attrScale_ids)

        

            return res
            ...
            
        raise(Exception("还没有能力复制该对象"))





    def obj_new(self,type):
        res={}
        if type=="dramaDialogue":            
            res = md.dramaDialogue().__dict__
            res['id']['value']=self.getUuid(self.dramaDialogue_ids)
            res['dialogue']=self.obj_new("LocalText")
            res['title']=self.obj_new("LocalText")

            return res

        if type=='condition':
            res = md.condition().__dict__
            res['id']['value']=self.getUuid(self.condition_ids)
            return res

        if type in ["function","openFunction"]:
            res = md.function().__dict__
            res['id']['value']=self.getUuid(self.function_ids)
            return res

        if type=="dramaOptions":
            res = md.dramaOptions().__dict__
            res['id']['value']=self.getUuid(self.dramaOptions_ids)
            res['costItem']['id']['value']=self.getUuid(self.GameItemCost_ids)
            res['text']=self.obj_new("LocalText")
            return res

        if type=="roleCreateFeature":
            res = md.roleCreateFeature().__dict__
            res['id']['value']=self.getUuid(self.roleCreateFeature_ids)
            res['type1Data']['introduceText']= self.obj_new("LocalText")
            res['type3Data']['desc']= self.obj_new("LocalText")
            res['tips']= self.obj_new("LocalText")
            res['name']= self.obj_new("LocalText")
            return res


        if type=="effect":
            res = md.roleEffect().__dict__
            res['id']['value']=self.getUuid(self.roleEffect_ids)
            return res

        if type =="LocalText":
            res = md.LocalText().__dict__
            res['key']['value']=self.getUuid(self.LocalText_Key,True)
            res['id']['value']=self.getUuid(self.LocalText_ids)
            return res
        
        if type =="fortuitousEvent":
            res = md.fortuitousEvent().__dict__
            res['id']['value']=self.getUuid(self.fortuitousEvent_ids)
            return res

        if type =="npcCondition":
            res = md.npcCondition().__dict__
            res['id']['value']=self.getUuid(self.npcCondition_ids)
            return res
        
  
        if type =="mapPosition":
            res = md.mapPosition().__dict__
            res['id']['value']=self.getUuid(self.mapPosition_ids)
            return res

        if type=="worldFortuitousEventBase":
            res=md.worldFortuitousEventBase().__dict__
            res['id']['value']=self.getUuid(self.worldFortuitousEventBase_ids)
            res['name']=self.obj_new("LocalText")
            return res
        

        if type=="itemProps":
            res=md.itemProps().__dict__
            res['id']['value']=self.getUuid(self.itemProps_ids)
            res['name']=self.obj_new("LocalText")
            res['desc']=self.obj_new("LocalText")    
            res['itemPill']['roleEffect']=md.roleEffect().__dict__
            res['itemPill']['roleEffect']['id']['value']=self.getUuid(self.roleEffect_ids)
            res['itemTreasureMap']['costItem']['id']['value']=self.getUuid(self.GameItemCost_ids)
            res['itemHorse']=md.itemHorse().__dict__
            res['itemHorse']['desc']=self.obj_new("LocalText")    
            return res        

        if type=="taskBase":
            res=md.taskBase().__dict__
            res['id']['value']=self.getUuid(self.taskBase_ids)
            res['name']=self.obj_new("LocalText")
            res['desc']=self.obj_new("LocalText")
            return res
        

        if type=="dramaNpc":
            res=md.DramaNpc().__dict__
            res['id']['value']=self.getUuid(self.dramaNpc_ids)
            res['name']=self.obj_new("LocalText")
            return res
        

        if type=="schoolSmall":
            res=md.schoolSmall().__dict__
            res['id']['value']=self.getUuid(self.schoolSmall_ids)
            res['lastName']=self.obj_new("LocalText")
            return res        

        if type=="schoolInitScale":
            res=md.schoolInitScale().__dict__
            res['id']['value']=self.getUuid(self.schoolInitScale_ids)
            res['lastName']=self.obj_new("LocalText")
            return res    
        
        if type=="dungeonBase":
            res=md.dungeonBase().__dict__
            res['id']['value']=self.getUuid(self.dungeonBase_ids)
            res['name']=self.obj_new("LocalText")
            return res
        
                
        if type=="horseModel":
            res=md.horseModel().__dict__
            res['id']['value']=self.getUuid(self.horseModel_ids)
            res['name']=self.obj_new("LocalText")
            return res

                
        if type=="schoolCustom":
            res=md.schoolCustom().__dict__
            res['id']['value']=self.getUuid(self.schoolCustom_ids)
            res['name']=self.obj_new("LocalText")
            return res

                
        if type=="npcAddWorld":
            res=md.npcAddWorld().__dict__
            res['id']['value']=self.getUuid(self.npcAddWorld_ids)
            res['name1']=self.obj_new("LocalText")
            res['name2']=self.obj_new("LocalText")
            return res

                
        if type=="reward":
            res = md.dropID().__dict__
            res['id']['value']=self.getUuid(self.GameItemReward_ids)
            return res





        
        return res
    
    def __init__(self,ctx):
        self.jsonpath=ctx.db['gamePath']+"\\Mod\modFQA\配置修改教程\配置（只读）Json格式"
        self.ctx=ctx
        self.db=ctx.db
        modPath=ctx.db['modPath']
        if not 'dramaDialogue' in ctx.db:
            #随便判断一下数据库里面是否有剧情，没有就直接重载数据库
            self.inital_db()
        modDict={}
        dirs = os.listdir(modPath)
        for modName in dirs:
            modpath = os.path.join(modPath,modName)
            modinfo_file = os.path.join(modpath,"ModProject\ModProject.cache")
            with open(modinfo_file,mode="r",encoding="utf-8") as m:
                obj = json.loads(m.read())
                obj['path']=modpath
                modDict[obj['soleID']]=obj
        self.modDict=modDict


    def obj_analysis(self,obj,key="mod"):

        if obj=={'groupName': [], 'items': []}:
            return        

        if 'value' in obj and len(obj)==1:
            value=obj['value']
            if type(value)==str and "\"" in value:                
                obj_json=json.loads(value)
                if "dressMan" in obj_json:
                    if not 'NpcSpecial' in self.objects:
                        self.objects['NpcSpecial']={}
                    self.objects['NpcSpecial'][obj_json['id']['value']]=obj_json

                    if not 'dress' in self.objects:
                        self.objects['dress']={}
                    self.objects['dress'][obj_json['dressWoman']['id']['value']]=obj_json['dressWoman']
                    self.objects['dress'][obj_json['dressMan']['id']['value']]=obj_json['dressMan']

                    return
                if 'rewardID' in obj_json:
                    self.objects['rewardCount'][obj_json['rewardID']['value']]=obj_json
                    for i in obj_json['items']:
                        self.obj_analysis(i,"reward")  
            else:
                return


        if key in ["name","tips","desc","text","name1","name2","lastName","introduceText","dialogue","title"]:
            key="LocalText"    
  
        if key in ['dropID','firstReward']:
            key='reward'

        if 'unction' in key:
            key='function'
        
        if type(obj)==dict:
            for k in obj:
                child=obj[k]
                if type(child)==dict:
                    self.obj_analysis(obj[k],k)
                if type(child)==list:
                    for c in child:
                        self.obj_analysis(c,key)

            if 'id' in obj:
                if not key in self.objects:
                    self.objects[key]={}
                storage=self.objects[key]
                try:
                    storage[obj['id']['value']]=[obj]
                except:
                    ss=0
                
                return


    def modRead(self,path):
        modDataPath = os.path.join(path,"ModProject\ModData.cache")
        modData={}
        with open(modDataPath,mode='r',encoding='utf-8') as md:
            modData=json.loads(md.read())
            md.close()      
        print('读取ModData.cache文件完成')

        self.LocalText_Key=self.db['LocalText_Key'].copy()
        self.LocalText_ids=self.db['LocalText_ids'].copy()
        self.dramaOptions_ids=self.db['DramaOptions_ids'].copy()
        self.dramaDialogue_ids=self.db['dramaDialogue_ids'].copy()
        self.GameItemReward_rewardids=self.db['GameItemReward_rewardids'].copy()
        self.GameItemCost_ids=self.db['GameItemCost_ids'].copy()
        self.GameItemReward_ids=self.db['GameItemReward_ids'].copy()
        self.roleCreateFeature_ids=self.db['roleCreateFeature_ids'].copy()
        self.roleEffect_ids=self.db['roleEffect_ids'].copy()
        self.fortuitousEvent_ids=self.db['FortuitousEvent_ids'].copy()
        self.npcCondition_ids=self.db['NpcCondition_ids'].copy()
        self.mapPosition_ids=self.db['MapPosition_ids'].copy()
        self.worldFortuitousEventBase_ids=self.db['WorldFortuitousEventBase_ids'].copy()
        self.itemProps_ids=self.db['ItemProps_ids'].copy()
        self.taskBase_ids=self.db['taskBase_ids'].copy()
        self.dramaNpc_ids=self.db['DramaNpc_ids'].copy()
        self.schoolSmall_ids=self.db['SchoolSmall_ids'].copy()
        self.schoolInitScale_ids=self.db['SchoolInitScale_ids'].copy()
        self.dungeonBase_ids=self.db['DungeonBase_ids'].copy()
        self.NpcSpecial_ids=self.db['NpcSpecial_ids'].copy()
        self.BattleUnitAttr_ids=self.db['BattleUnitAttr_ids'].copy()

        
        
        self.horseModel_ids=[]
        self.condition_ids=[]
        self.function_ids=[]
        self.effect_ids=[]
        self.reward_ids=[]
        self.npcAddWorld_ids=[]
        self.dress_ids=[]
        self.schoolCustom_ids=[]
        self.GameItemRewards={}
        

        self.objects={
            'rewardCount':{}
        }
        self.obj_analysis(modData)
        
        for key in self.objects:
            tp=key+"_ids"
            if tp=='rewardCount_ids':
                tp="GameItemReward_ids"

            if tp=="costItem_ids":
                tp="GameItemCost_ids"
            if hasattr(self,tp):
                ids = getattr(self,tp)
                ids_new =list(x for x in self.objects[key]) 
                setattr(self,tp,ids_new+ids)
            else:
                setattr(self,tp,list(x for x in self.objects[key]) )

        return modData
    
    def modSave(self,path,modData):
        modDataPath = os.path.join(path,"ModProject\ModData.cache")
        with open(modDataPath,mode='w',encoding='utf-8') as md:
            md.write(json.dumps(modData,ensure_ascii=False))
            md.close()


    def inital_db(self):
        #常用base文件加载到数据库
        self.db['dramaDialogue']=self.get_currentObj('dramaDialogue')
        self.db['DramaOptions']=self.get_currentObj('DramaOptions')
        self.db['LocalText']=self.get_currentObj('LocalText')
        self.db['GameItemReward']=self.get_currentObj('GameItemReward')
        self.db['GameItemCost']=self.get_currentObj('GameItemCost')
        self.db['roleEffect']=self.get_currentObj('roleEffect')
        self.db['MapPosition']=self.get_currentObj('MapPosition')
        self.db['RoleLogLocal']=self.get_currentObj('RoleLogLocal')
        self.db['FortuitousEvent']=self.get_currentObj('FortuitousEvent')
        self.db['ItemProps']=self.get_currentObj('ItemProps')
        self.db['roleCreateFeature']=self.get_currentObj('roleCreateFeature')
        self.db['NpcCondition']=self.get_currentObj('NpcCondition')
        self.db['WorldFortuitousEventBase']=self.get_currentObj('WorldFortuitousEventBase')
        self.db['taskBase']=self.get_currentObj('taskBase')
        self.db['DramaNpc']=self.get_currentObj('DramaNpc')
        self.db['SchoolSmall']=self.get_currentObj('SchoolSmall')
        self.db['SchoolInitScale']=self.get_currentObj('SchoolInitScale')
        self.db['DungeonBase']=self.get_currentObj('DungeonBase')
        self.db['NpcSpecial']=self.get_currentObj('NpcSpecial')
        self.db['BattleUnitAttr']=self.get_currentObj('BattleUnitAttr')
        


        LocalText=self.db['LocalText']
        DramaOptions=self.db['DramaOptions']
        GameItemCost=self.db['GameItemCost']
        dramaDialogue=self.db['dramaDialogue']
        GameItemReward=self.db['GameItemReward']
        roleCreateFeature=self.db['roleCreateFeature']
        roleEffect=self.db['roleEffect']
        FortuitousEvent=self.db['FortuitousEvent']
        NpcCondition=self.db['NpcCondition']
        MapPosition=self.db['MapPosition']
        WorldFortuitousEventBase=self.db['WorldFortuitousEventBase']
        ItemProps=self.db['ItemProps']
        taskBase=self.db['taskBase']
        DramaNpc=self.db['DramaNpc']
        SchoolSmall=self.db['SchoolSmall']
        SchoolInitScale=self.db['SchoolInitScale']
        DungeonBase=self.db['DungeonBase']
        NpcSpecial=self.db['NpcSpecial']
        BattleUnitAttr=self.db['BattleUnitAttr']


        self.db['LocalText_Key']=list(LocalText[x]['key'] for x in LocalText)
        self.db['LocalText_ids']=list(int(x) for x in LocalText)
        self.db['DramaOptions_ids']=list(int(x) for x in DramaOptions)
        self.db['GameItemCost_ids']=list(int(x) for x in GameItemCost)
        self.db['dramaDialogue_ids']=list(int(x) for x in dramaDialogue)
        self.db['roleCreateFeature_ids']=list(int(x) for x in roleCreateFeature)
        self.db['roleEffect_ids']=list(int(x) for x in roleEffect)
        self.db['FortuitousEvent_ids']=list(int(x) for x in FortuitousEvent)
        self.db['NpcCondition_ids']=list(int(x) for x in NpcCondition)
        self.db['MapPosition_ids']=list(int(x) for x in MapPosition)
        self.db['WorldFortuitousEventBase_ids']=list(int(x) for x in WorldFortuitousEventBase)
        self.db['ItemProps_ids']=list(int(x) for x in ItemProps)
        self.db['GameItemReward_rewardids']=list(int(GameItemReward[x]['rewardID']) for x in GameItemReward)
        self.db['GameItemReward_ids']=list(int(x) for x in GameItemReward)
        self.db['taskBase_ids']=list(int(x) for x in taskBase)
        self.db['DramaNpc_ids']=list(int(x) for x in DramaNpc)
        self.db['SchoolSmall_ids']=list(int(x) for x in SchoolSmall)
        self.db['SchoolInitScale_ids']=list(int(x) for x in SchoolInitScale)
        self.db['DungeonBase_ids']=list(int(x) for x in DungeonBase)
        self.db['NpcSpecial_ids']=list(int(x) for x in NpcSpecial)
        self.db['BattleUnitAttr_ids']=list(int(x) for x in BattleUnitAttr)

        


    def get_currentObj(self,obj_name):
        filepath = f"{self.jsonpath}\{obj_name}.json"
        with open(filepath,mode='r',encoding='utf-8') as r:
            res = json.loads(r.read())
            res = {x['id']:x for x in res}
            r.close()
        return res